<!DOCTYPE html>
<html>
<head>
	<title></title>
	<link rel="stylesheet" type="text/css" href="../公用CSS文件/all.css" />
	<meta charset="utf-8">
	<script type="text/javascript" src="../js/jquery.min.js"></script> 	<script type="text/javascript" src="../js/js.js"></script>
	<style type="text/css">

	</style>
</head>
<body>

<div class="dt">PHP面向对象概述</div>
<ul>
	
	<div class="ltable showimg">面向对象相关概念</div>
	<div class="img">
		<table>
			<tr>
				<th>术语</th><th>说明</th>
			</tr>
			<tr>
				<td>OOP</td><td>Object Oriented(面向) Programming(编程)，一种计算机语言设计思想，以对象这种语法实体封装其中的属性和方法</td>
			</tr>
			<tr>
				<td>对象Object</td><td>对象是OOP中借用对现实事物的描述定义的一类语法实体，是类的实例化，通常也会是OOP语言的一种数据类型</td>
			</tr>
			<tr>
				<td>类class</td><td>类是拥有共同属性和方法的对象的集合，PHP的OOP是以类为基础产生的对象，声明对象必须先声明它的类</td>
			</tr>
		</table>
	</div>

	<div class="ltable showimg">类运算符</div>
	<div class="img">
		<table>
			<tr>
				<th>运算符</th><th>名称</th><th>作用</th>
			</tr>
			<tr>
				<td> -> </td><td>对象运算符</td><td> 访问非静态属性和方法 </td>
			</tr>
			<tr>
				<td> :: </td><td>范围解析操作符</td><td> 访问类常量和静态成员 </td>
			</tr>
		</table>
		<li>self::在类中使用，访问类中静态成员和类常量，parent::在子类访问父类，static::访问仅在被定义的类中访问，而当封装该语句的方法被继承时，不会被执行</li>
		<li>如果在子类使用parent调用父类方法，该方法内部的$this在该场景下指向子类而不是父类</li>
	</div>


	
	<div class="ltable showimg">类和对象的声明</div>
	<div class="img">
		<img src="img/类的声明.png">
	</div>

	<div class="ltable showimg">类修饰符</div>
	<div class="img">
		<table>
			<tr>
				<th>修饰符</th><th>说明</th>
			</tr>
			<tr>
				<td>abstract</td><td>修饰一个类，标识其为抽象类</td>
			</tr>
			<tr>
				<td>final</td><td>修饰一个类，标识其不可被继承，也可以标识类方法不可被覆盖</td>
			</tr>
		</table>
	</div>

</ul>

<div class="dt">PHP类成员和类方法</div>
<ul>
	<div class="ltable showimg">类成员修饰符</div>
	<div class="img">
		<table>
			<tr>
				<th>修饰符</th><th>意义</th>
			</tr>
			<tr>
				<td>public</td><td>该成员能通过实例化对象、子类、类内访问</td>
			</tr>
			<tr>
				<td>protected</td><td>该成员能通过子类、类内访问，但不可通过实例化对象访问</td>
			</tr>
			<tr>
				<td>private</td><td>该成员仅能在类内访问，声明了static能在外部通过类名访问，但这仍然是通过该类访问</td>
			</tr>
			<tr>
				<td>static</td><td>该成员可以不实例化对象直接在类外通过类名访问</td>
			</tr>
			<tr>
				<td>var</td><td>声明一个类属性，和使用public关键字是一样的效果，但类属性不能直接声明，必须要使用其中至少一个关键字</td>
			</tr>
			<tr>
				<td>final</td><td>标识一个方法不可被继承，也可以标识一个类不可被继承</td>
			</tr>
		</table>
		<li>public、protected、private三种标识是关于访问权限的，只能同时声明一个，如果不声明，则默认是public的权限</li>
		<li>static是指该成员可以通过类名访问，由于不需要构建实例化对象，仅在通过类名访问时，其比非静态变量访问速度快约3倍，但如果通过实例化对象访问，没有任何区别</li>
	</div>

	

	<div class="ltable showimg">访问类成员</div>
	<div class="img">
		<table>
			<tr>
				<th>成员</th><th>类中访问</th><th>类外访问</th>
			</tr>
			<tr>
				<td>静态属性</td><td>self::$属性名</td><td>类名::$属性名 &nbsp;&nbsp;或者 &nbsp;&nbsp;实例化对象::$属性名</td>
			</tr>
			<tr>
				<td>静态方法</td><td>self::方法名()</td><td>类名::方法名() &nbsp;&nbsp;或者 &nbsp;&nbsp;实例化对象::方法名()</td>
			</tr>
			<tr>
				<td>非静态属性</td><td>$this->属性名</td><td>实例化对象->属性名</td>
			</tr>
			<tr>
				<td>非静态方法</td><td>$this->方法名()</td><td>实例化对象->方法名()</td>
			</tr>
			<tr>
				<td>类常量</td><td>self::常量名</td><td>类名::常量名 &nbsp;&nbsp;或者 &nbsp;&nbsp;实例化对象::常量名</td>
			</tr>
		</table>
		<li>类中的静态属性需要添加标识符“$”是因为要和常量区分</li>
	</div>

</ul>

<div class="dt">PHP类常量和类魔法常量</div>
<ul>
	
	<div class="ltable showimg">类常量</div>
	<div class="img">
		<table>
			<tr>
				<th>类常量</th><th>语法格式</th>
			</tr>
			<tr>
				<td>定义类常量</td><td>const 常量名 = 值，类常量“类中的常量”，是在类中但不是类方法中声明的常量，除了语法格式有区别，性质和全局常量一致</td>
			</tr>
			<tr>
				<td>调用类常量</td><td>类中self::常量名，类外:类名::常量名 &nbsp;或者 &nbsp;实例化对象::常量名</td>
			</tr>
		</table>
		<li>类的静态属性调用之所以要加“$”符号，是为了和常量区分</li>
		<li>类常量被定义时，如果赋值必须赋予明确的值，不能进行任何运算和处理</li>
		<li>接口中也可以声明常量，接口常量和类常量唯一的不同之处在于接口常量不能被重构</li>
	</div>

	<div class="ltable showimg">类魔法常量</div>
	<div class="img">
		<table>
			<tr>
				<th>常量</th><th>说明</th>
			</tr>
			<tr>
				<td>__CLASS__</td><td>类中使用，返回该类类名</td>
			</tr>
			<tr>
				<td>::class</td><td>5.5版本更新时加入，类中使用返回命名空间和类名的字符串</td>
			</tr>
		</table>
	</div>
 
</ul>

<div class="dt">PHP魔术方法</div>
<ul>
	
	<div class="ltable showimg">魔术方法概念</div>
	<div class="img">
		<li>魔术方法是PHP中预定义的一类方法，特征是方法名以"__"双引号开头，作用是当满足预设的某些条件时，自动被调用，这些魔术方法需要在类中声明才可以作为类方法使用</li>
		<li>自定义的函数也可以用“__”双引号开头，只要该方法不存在就可以定义</li>
		<li>魔术方法的访问权限必须是public，否则会报错</li>
	</div>

	<div class="ltable showimg">PHP魔术方法</div>
	<div class="img">
		<table>
			<tr>
				<th>方法</th><th>作用</th><th>参数</th><th>说明</th>
			</tr>
			<tr>
				<td>__construct</td><td>在类被实例化时自动调用</td><td>声明时自定义</td><td>常用来初始化类成员属性或调用其他类方法</td>
			</tr>
			<tr>
				<td>__destruct</td><td>在类被销毁时自动调用</td><td>无</td><td>脚本运行结束会自动释放所占的内存，所以这时候对象也会销毁</td>
			</tr>
			<tr>
				<td>__get</td><td>试图获取一个指定的不可见或不存在的成员属性的值时，自动调用</td><td>以"$"标识的属性名</td><td>该魔术方法参数变量接收属性名</td>
			</tr>
			<tr>
				<td>__set</td><td>当试图为不可访问或不存在的属性赋值时，自动被调用</td><td>以"$"标识的属性名 &nbsp;&nbsp;变量</td><td>第一个参数变量接受成员属性名，第二个参数变量接收赋值操作想要赋予的值</td>
			</tr>
			<tr>
				<td>__call</td><td>当调用不存在或不可访问的方法时自动被调用</ td><td>变量 &nbsp;&nbsp;变量</td><td>第一个变量接收调用的方法名 ， 第二个参数接收调用该方法时传递的参数数组</td>
			</tr>
			<tr>
				<td>__sleep</td><td>当对象被序列化时自动被调用</td><td>无</td><td>必须返回一个索引数组，该数组的值必须为成员属性名</td>
			</tr>
			<tr>
				<td>__wakeup</td><td>当对象被反序列化时自动被调用</td><td>无</td><td>在该方法内调用的成员属性如果被__sleep返回过，则为最终值，否则它是初始值</td>
			</tr>
			<tr>
				<td>__toString</td><td>当试图对该类进行echo和print输出操作时，调用该方法</td><td>无</td><td>该方法必须有一个返回值，如果返回字符串，试图输出这个对象，会输出它的返回值</td>
			</tr>
		</table>

		<li>魔术方法在满足条件时自动触发，所以没有返回值，仅仅执行一个过程</li>
		<li>__sleep方法return的成员属性会保留该对象的值，否则在反序列化的时候，该成员属性为初始值</li>
		<li>在对象被序列化时，方法会被保存，但如果转化为json，函数方法会丢失</li>
		<li>转化为json，永远会保留对象属性的最终值</li>
		<li>除了这些有用的魔术方法，还有一个__autoload方法，该方法性能开销巨大，但用处极小，不推荐使用，且官网已经公告将废弃</li>
	</div>

</ul>

<div class="dt">PHP类的继承</div>
<ul>

	<div class="ltable showimg">继承机制</div>
	<div class="img">
		<table>
			<tr>
				<th>继承</th><th>说明</th>
			</tr>
			<tr>
				<td>声明继承普通类(包含抽象类)</td><td>在定义类时声明：class 子类 extends 父类</td>
			</tr>
			<tr>
				<td>声明继承接口</td><td>在定义类时声明：class 子类 implements 接口,接口...</td>
			</tr>
			<tr>
				<td>类中调用父类成员</td><td>如果没有进行类成员重构，则和类中属性一样调用，也可以通过parent::指向父类调用(这样做的话无论是静态非静态都可以访问)</td>
			</tr>
			<tr>
				<td>类外调用</td><td>作为本类成员调用</td>
			</tr>
		</table>
		<li>一个类仅可以继承一个非接口的类，但可以继承多个接口类</li>
	</div>

	<div class="ltable showimg">final关键字</div>
	<div class="img">
		<li>final关键字标识的类不能被继承，标识的方法不能被重构，标识属性会报错</li>
		<li>private标识的私有成员不能被继承</li>
	</div>
</ul>

<div class="dt">PHP抽象类、接口、trait</div>
<ul>
	
	<div class="ltable showimg">抽象类</div>
	<div class="img">
		<table>
			<tr>
				<th>抽象类</th><th>说明</th>
			</tr>
			<tr>
				<td>概念</td><td>以abstract关键字声明的类，一般会包含抽象方法，如果声明了抽象方法，则必须在子类中具体化这个方法(完整声明该方法)</td>
			</tr>
			<tr>
				<td>抽象方法</td><td>在抽象类中声明的以abstract关键字声明的方法，标识为抽象方法的方法仅能声明方法名和参数，不能声明函数体</td>
			</tr>
		</table>
		<li>抽象类除了可以定义抽象方法和使用abstract标识之外，在声明时和普通类没什么区别，甚至可以不声明抽象方法</li>
		<li>声明为抽象类的类不能实例化，仅能被其他类继承，哪怕其中没有抽象方法</li>
		<li>抽象类也可以继承其他的类</li>
	</div>

	<div class="ltable showimg">接口</div>
	<div class="img">
		<table>
			<tr>
				<th>接口</th><th>说明</th>
			</tr>
			<tr>
				<td>概念</td><td>接口是一种类似抽象类的不拥有成员属性的特殊的语法实体，意义是为实施它的类提供一种约束</td>
			</tr>
			<tr>
				<td>声明</td><td>以interface关键字声明，结构类似普通类的结构，只是接口方法必须是public权限且不能有方法体</td>
			</tr>
			<tr>
				<td>继承</td><td>类似类的继承，但子接口不能重构父接口的成员</td>
			</tr>
			<tr>
				<td>实现</td><td>使用implements关键字声明实施，语法为类 &nbsp;&nbsp;implements &nbsp;&nbsp;接口,接口...</td>
			</tr>
			<tr>
				<td>接口常量</td><td>在接口中定义的常量，和类常量只有一点不同：接口常量不能被重构</td>
			</tr>
		</table>
		<li>由于接口的成员不能被重构，所以实际上一个实施接口的类，被实施的方法也必须是public的访问权限</li>
		<li>接口虽然不能拥有属性成员，但在声明时不会报错，在实例化实现它的类时才会抛出fatal error致命错误</li>
		<li>接口常量无法被实现它的类重构，但能被实现它的类的子类重构</li>
		<li>如果接口方法的参数有默认值，实施它的类方法也必须有默认值，这时候其实接口方法的默认值是无效的，意义仅在于约束实现该方法的参数需要设置默认值，此外，实现接口方法时可以多声明参数</li>
		<li>PHP5.6之前，如果接口方法参数约束为类的实例，实现它的方法也可以约束为该类子类的实例，5.6之后开始严格化</li>
	</div>

	<div class="ltable showimg">trait特质</div>
	<div class="img">
		<table>
			<tr>
				<th>trait</th><th>说明</th>
			</tr>
			<tr>
				<td>概念</td><td>trait是PHP5.5引入的一种特殊类，自身不能被实例化，仅为继承它的类提供一些方法和属性，并且优化级高于extends继承而来的方法</td>
			</tr>
			<tr>
				<td>声明</td><td>以trait关键字声明，结构类似普通class，拥有普通类的所有特征，甚至可以拥有抽象方法</td>
			</tr>
			<tr>
				<td>继承</td><td>在类中使用use 包含命名空间的trait名继承，可以用逗号分隔多个trait同时继承多个，并且trait之间也可以这样做实现互相继承</td>
			</tr>
		</table>
		<li>use过trait的类，即使继承过其他类在类中调用parent::方法，如果use的trait中有同名的方法，依然是trait优先(trait也是一种继承机制)</li>
		<li>当继承的多个trait之间有同名方法时，可以使用insteadof声明使用哪个trait的方法替代另一个</li>
	</div>

		
</ul>


<div class="dt">PHP对象运算和转化</div>
<ul>
	
	<div class="ltable showimg">对象比较运算</div>
	<div class="img">
		<table>
			<tr>
				<th>运算符</th><th>说明</th>
			</tr>
			<tr>
				<td> == </td><td> 当两个对象的属性和属性值相等，并且为同一个类的实例化，那么它们相等</td>
			</tr>
			<tr>
				<td> === </td><td>两个对象必须是同一个实例时，它们才相等</td>
			</tr>
			<tr>
				<td> 其他比较运算符 </td><td>不可比较，永远为假</td>
			</tr>
		</table>
		<li>两个对象恒等一般是引用赋值才恒等，即使使用clone关键字复制对象，也不是恒等</li>
	</div>

	<div class="ltable showimg">json转化和序列化</div>
	<div class="img">
		<table>
			<tr>
				<th>函数</th><th>作用</th><th>参数</th><th>返回值</th>	
			</tr>
			<tr>
				<td>json_encode</td><td>将数据转化为json字符串</td><td>任意数据(匿名函数表达式也算object)</td><td>json字符串</td>
			</tr>
			<tr>
				<td>json_decode</td><td>解析json字符串</td><td>json字符串 &nbsp;&nbsp;&nbsp;布尔值=false</td><td>解析json得到的数据，第二参数为true会在对象和关联数组两种可能结果之间选择关联数组</td>
			</tr>
			<tr>
				<td>serialize</td><td>序列化数据</td><td>数据(一般为数组和对象)</td><td>字符串</td>
			</tr>
			<tr>
				<td>unserialize</td><td>序列化后的字符串</td><td>字符串</td><td>解析出来的数据</td>
			</tr>
		</table>
		<li>json仅仅转化成员属性，解析出来后方法会丢失，serialize序列化不会丢失方法(官网说明有误亲测N次)</li>
	</div>

	<div class="ltable showimg">对象和类关系运算</div>
	<div class="img">
		<table>
			<tr>
				<th>关键字</th>
				<th>作用</th>
				<th>说明</th>
			</tr>
			<tr>
				<td>instanceof</td>
				<td>判断一个对象是否是一个类或其子类的实例，或实施了该接口或其子接口的类的实例</td>
				<td>$a instanceof a</td>
			</tr>
		</table>
		<li>类名在PHP语言中通常作为字符串传递，但在instanceof中必须直接使用类名和不是传递字符串</li>
	</div>

	<div class="ltable showimg">对象和类关系运算函数</div>
	<div class="img">
		<table>
			<tr>
				<th>函数</th><th>作用</th><th>参数</th><th>运算符</th>
			</tr>
			<tr>
				<td>is_a</td>
				<td>判断一个对象是否是一个类或其子类的实例，或实施了该接口或其子接口的类的实例</td>
				<td>object对象  str类名</td>
				<td>布尔值</td>
			</tr>
			<tr>
				<td>is_subclass_of</td>
				<td>判断一个对象是否是一个类的子类的实例，或实施了该接口或其子接口的类的实例</td>
				<td>object对象  str类名</td>
				<td>布尔值</td>
			</tr>
		</table>
		<li>is_a和instanceof作用一致，但用法不同，其类名按照PHP通常语法使用字符串传递，其实在实际项目中，通常使用非字符串的a::class传递类名，
			它返回字符串，同时拥有更高的语义识别性表示这是一个类作为字符串传入，还有省略命名空间</li>
	</div>
</ul>

<div class="dt">strait</div>


<div class="dt">PHP面向对象其他知识</div>
<ul>
	
	<div class="ltable showimg">单例模式和工厂模式</div>
	<div class="img">
		<li>单例模式一般是定义一个静态方法，访问该方法会为特定的类属性赋值，然后返回一个实例化对象，实际上流行的框架都不会采用这种做法，实际开发中也不会采用，而是使用配置文件和构造函数参数默认值</li>
		<li>工厂模式是根据传入的参数的不同调用不同的代码块实现不同的功能，在面向对象中，具体做法是通过过渡类实例化时的参数不同实例化不同的其他类</li>
	</div>

	<div class="ltable showimg">对象数据类型</div>
	<div class="img">
		<li>对象这种数据类型可以被当成数组使用，当foreach时和其所有可访问的属性及属性值组成的关联数组一致</li>
	</div>
</ul>





</body>
</html>
